import { _decorator, Component, Node, tween, UIOpacity, v3, Widget } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('BasePanel')
export class BasePanel extends Component {

    /** 面板 */
    @property(Node)
    panel: Node = null!

    /** 面板透明度 */
    @property(UIOpacity)
    opacity: UIOpacity = null!

    onLoad() {
        let node: Node = this.node
        this.panel = node.getChildByName('Panel')
        if (this.panel) {
            this.opacity = this.panel.getComponent(UIOpacity)
            if (!this.opacity) {
                this.opacity = this.panel.addComponent(UIOpacity)
            }
            let w1: Widget = node.addComponent(Widget)
            if (w1) {
                w1.isAlignLeft = true
                w1.isAlignRight = true
                w1.isAlignTop = true
                w1.isAlignBottom = true
                w1.left = 0
                w1.right = 0
                w1.top = 0
                w1.bottom = 0
            }
            let mask: Node = node.getChildByName('Mask')
            if (mask) {
                let w2: Widget = mask.addComponent(Widget)
                if (w2) {
                    w2.isAlignLeft = true
                    w2.isAlignRight = true
                    w2.isAlignTop = true
                    w2.isAlignBottom = true
                    w2.left = 0
                    w2.right = 0
                    w2.top = 0
                    w2.bottom = 0
                }
            }
        }
        if (this.opacity) {
            this.opacity.opacity = 0
        }
    }

    start() {
        this.show()
    }

    /** 面板名称 */
    panelName: string = '面板'

    /** 打开，不可以在按钮组件中直接使用 */
    show(onOpen?: () => void) {
        this.in('pop', onOpen)
    }

    /** 关闭，不可以在按钮组件中直接使用 */
    close(onClose?: () => void) {
        this.out('pop', onClose)
    }

    /** 打开，可以在按钮组件中直接使用 */
    directShow() {
        this.in('pop')
    }

    /** 关闭，可以在按钮组件中直接使用 */
    directClose() {
        this.out('pop')
    }

    /**
     * 打开面板
     * @param type 方式
     * @param onOpen 打开后执行的方法
     */
    in(type: 'pop' | 'fade', onOpen?: () => void) {
        switch(type) {
            case 'pop':
                let scale1 = this.panel.getScale()
                let scale2 = scale1.clone().multiplyScalar(1.07)
                tween(this.panel)
                    .call(() => {
                        this.panel.setScale(v3(0, 0, 0))
                        if (this.opacity) {
                            this.opacity.opacity = 255
                        }
                    })
                    .to(.25, { scale: scale2 }, { easing: "quadOut" })
                    .to(.15, { scale: scale1 }, { easing: "quadOut" })
                    .call(() => {
                        if (onOpen) {
                            onOpen()
                        }
                    })
                    .start()
                break
            case 'fade':
                if (this.opacity) {
                    tween(this.opacity)
                        .call(() => {
                            this.opacity.opacity = 0
                        })
                        .to(.5, { opacity: 255 })
                        .call(() => {
                            if (onOpen) {
                                onOpen()
                            }
                        })
                        .start()
                } else {
                    if (onOpen) {
                        onOpen()
                    }
                }
                break
        }
    }

    /**
     * 关闭面板
     * @param type 方式
     * @param onClose 关闭后执行的方法
     */
    out(type: 'pop' | 'fade', onClose?: () => void) {
        switch(type) {
            case 'pop':
                let scale1 = this.panel.getScale()
                let scale2 = scale1.clone().multiplyScalar(1.07)
                tween(this.panel)
                    .to(.15, { scale: scale2 }, { easing: "quadIn" })
                    .to(.25, { scale: v3(0, 0, 0) }, { easing: "quadIn" })
                    .call(() => {
                        this.node.removeFromParent()
                        if (onClose) {
                            onClose()
                        }
                    })
                    .start()
                break
            case 'fade':
                if (this.opacity) {
                    tween(this.opacity)
                        .to(.5, { opacity: 0 })
                        .call(() => {
                            this.node.removeFromParent()
                            if (onClose) {
                                onClose()
                            }
                        })
                        .start()
                } else {
                    this.node.removeFromParent()
                    if (onClose) {
                        onClose()
                    }
                }
                break
        }
    }
}


